package com.studyhub.message.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.studyhub.api.message.entity.NoticeMessageEntity;
import com.studyhub.api.message.vo.NoticeMessagePage;
import com.studyhub.api.message.vo.NoticeMessageQueryVO;
import com.studyhub.api.message.vo.NoticeMessageStatsVO;
import com.studyhub.core.result.PageResult;
import com.studyhub.core.result.Result;
import com.studyhub.core.result.ResultCode;
import com.studyhub.message.service.INoticeMessageService;
import com.studyhub.web.utils.UserAuthUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

import com.studyhub.web.annotation.Inner;

/**
 * @Description  通知消息控制器
 * @Author YWF
 * @Version 1.0.0
 * @Date 2025/9/26 09:44
 */

@Slf4j
@Tag(name = "通知服务")
@Validated
@RestController
@RequestMapping("/notice")
public class NoticeMessageController {
    
    @Autowired
    private INoticeMessageService noticeMessageService;

    @Operation(summary = "分页查询通知消息")
    @PostMapping("/page")
    public Result<PageResult<NoticeMessagePage>> pageNoticeMessages(@RequestBody NoticeMessageQueryVO queryVO) {
        long startTime = System.currentTimeMillis();
        Long userId = UserAuthUtil.getUserId().longValue();
        log.info("用户[{}]开始分页查询通知消息，查询条件: {}", userId, queryVO);
        
        try {
            IPage<NoticeMessagePage> page = noticeMessageService.pageNoticeMessages(queryVO, userId);
            log.info("用户[{}]分页查询通知消息成功，返回{}条记录，耗时{}ms", 
                    userId, page.getRecords().size(), System.currentTimeMillis() - startTime);
            return Result.success(PageResult.setResult(page));
        } catch (Exception e) {
            log.error("用户[{}]分页查询通知消息失败，耗时{}ms，错误: {}", 
                    userId, System.currentTimeMillis() - startTime, e.getMessage(), e);
            throw e;
        }
    }
    
    @Operation(summary = "获取通知消息统计信息")
    @GetMapping("/stats")
    public Result<NoticeMessageStatsVO> getNoticeMessageStats() {
        long startTime = System.currentTimeMillis();
        Long userId = UserAuthUtil.getUserId().longValue();
        log.info("用户[{}]开始获取通知消息统计信息", userId);
        
        try {
            NoticeMessageStatsVO stats = noticeMessageService.getNoticeMessageStats(userId);
            log.info("用户[{}]获取通知消息统计成功，总数:{}, 未读:{}, 耗时{}ms", 
                    userId, stats.getTotalCount(), stats.getUnreadCount(), System.currentTimeMillis() - startTime);
            return Result.success(stats);
        } catch (Exception e) {
            log.error("用户[{}]获取通知消息统计失败，耗时{}ms，错误: {}", 
                    userId, System.currentTimeMillis() - startTime, e.getMessage(), e);
            throw e;
        }
    }
    
    @Operation(summary = "获取未读消息数量")
    @GetMapping("/unread/count")
    public Result<Long> getUnreadCount() {
        Long userId = UserAuthUtil.getUserId().longValue();
        long count = noticeMessageService.getUnreadCount(userId);
        return Result.success(count);
    }
    
    @Inner
    @Operation(summary = "发送通知消息(内部调用)")
    @PostMapping("/send")
    public Result<Boolean> sendNoticeMessage(@RequestBody @Validated NoticeMessageEntity message) {
        // 设置发送时间
        message.setMessageTime(LocalDateTime.now());
        
        boolean result = noticeMessageService.sendNoticeMessage(message);
        if (result) {
            return Result.msgSuccess("发送成功");
        } else {
            return Result.msgError("发送失败");
        }
    }
    
    @Inner
    @Operation(summary = "批量发送通知消息(内部调用)")
    @PostMapping("/send/batch")
    public Result<Integer> batchSendNoticeMessages(@RequestBody @Validated List<NoticeMessageEntity> messages) {
        // 为每条消息设置时间
        LocalDateTime now = LocalDateTime.now();
        messages.forEach(message -> {
            message.setMessageTime(now);
        });
        
        int successCount = noticeMessageService.batchSendNoticeMessages(messages);
        return Result.success("成功发送 " + successCount + " 条消息", successCount);
    }
    
    @Operation(summary = "标记消息为已读")
    @PutMapping("/{messageId}/read")
    public Result<Boolean> markAsRead(@PathVariable Long messageId) {
        long startTime = System.currentTimeMillis();
        Long userId = UserAuthUtil.getUserId().longValue();
        log.info("用户[{}]开始标记消息[{}]为已读", userId, messageId);
        
        try {
            boolean result = noticeMessageService.markAsRead(messageId, userId);
            if (result) {
                log.info("用户[{}]标记消息[{}]为已读成功，耗时{}ms", 
                        userId, messageId, System.currentTimeMillis() - startTime);
                return Result.msgSuccess("标记成功");
            } else {
                log.warn("用户[{}]标记消息[{}]为已读失败，耗时{}ms", 
                        userId, messageId, System.currentTimeMillis() - startTime);
                return Result.msgError("标记失败");
            }
        } catch (Exception e) {
            log.error("用户[{}]标记消息[{}]为已读异常，耗时{}ms，错误: {}", 
                    userId, messageId, System.currentTimeMillis() - startTime, e.getMessage(), e);
            throw e;
        }
    }
    
    @Operation(summary = "批量标记消息为已读")
    @PutMapping("/read/batch")
    public Result<Integer> batchMarkAsRead(@RequestBody List<Long> messageIds) {
        Long userId = UserAuthUtil.getUserId().longValue();
        int successCount = noticeMessageService.batchMarkAsRead(messageIds, userId);
        return Result.success("成功标记 " + successCount + " 条消息为已读", successCount);
    }
    
    @Operation(summary = "标记所有消息为已读")
    @PutMapping("/read/all")
    public Result<Integer> markAllAsRead() {
        Long userId = UserAuthUtil.getUserId().longValue();
        int successCount = noticeMessageService.markAllAsRead(userId);
        return Result.success("成功标记 " + successCount + " 条消息为已读", successCount);
    }
    
    @Operation(summary = "删除消息")
    @DeleteMapping("/delete")
    public Result<Integer> deleteMessages(@RequestBody List<Long> messageIds) {
        Long userId = UserAuthUtil.getUserId().longValue();
        int successCount = noticeMessageService.deleteMessages(messageIds, userId);
        return Result.success("成功删除 " + successCount + " 条消息", successCount);
    }

    //01.测试-向指定用户发送通知(内部调用)
    @Inner
    @Operation(summary = "测试发送通知(内部调用)")
    @RequestMapping("/test/send/{userId}")
    public Result<String> sendNotice(@PathVariable Long userId){
        NoticeMessageEntity noticeMessage = new NoticeMessageEntity();
        noticeMessage.setUserId(userId);
        noticeMessage.setMessageTime(LocalDateTime.now());
        noticeMessage.setMessageTitle("测试通知");
        noticeMessage.setMessageContent("你好 " + userId + "，这是一条测试通知消息");
        noticeMessage.setMessageType(1); // 1:紧急消息, 0:普通消息
        noticeMessage.setRead(false); // false:未读, true:已读
        noticeMessage.setStatus(false); // false:有效, true:无效
        
        boolean result = noticeMessageService.sendNoticeMessage(noticeMessage);
        if (result) {
            return Result.msgSuccess("测试通知发送成功");
        } else {
            return Result.msgError("测试通知发送失败");
        }
    }
    
    //02.公开测试接口-供测试人员使用
    //将来可能只用这个发送通知了
    @Inner(value = false)
    @Operation(summary = "消息发送-可用")
    @GetMapping("/public/test/send")
    public Result<String> publicSendNotice(@RequestBody NoticeMessageEntity noticeQuest){
        log.info("收到公开测试通知请求，目标用户ID: {}", noticeQuest.getUserId());
        
        try {
            NoticeMessageEntity noticeMessage = new NoticeMessageEntity();
            noticeMessage.setUserId(noticeQuest.getUserId()==null?10:noticeQuest.getUserId());
            noticeMessage.setMessageTime(LocalDateTime.now());
            noticeMessage.setMessageTitle(StringUtils.isNotBlank(noticeQuest.getMessageTitle())?noticeQuest.getMessageTitle():"测试通知");
            noticeMessage.setMessageContent(StringUtils.isNotBlank(noticeQuest.getMessageContent())?noticeQuest.getMessageContent():"测试通知");
            noticeMessage.setMessageType(noticeQuest.getMessageType()==null?1:noticeQuest.getMessageType());
            noticeMessage.setRead(false);
            noticeMessage.setStatus(false);
            
            boolean result = noticeMessageService.sendNoticeMessage(noticeMessage);
            if (result) {
                log.info("公开测试通知发送成功，用户ID: {}", noticeQuest.getUserId());
                return Result.msgSuccess("公开测试通知发送成功");
            } else {
                log.error("公开测试通知发送失败，用户ID: {}", noticeQuest.getUserId());
                return Result.msgError("公开测试通知发送失败");
            }
        } catch (Exception e) {
            log.error("公开测试通知发送异常，用户ID: {}, 错误信息: {}", noticeQuest.getUserId(), e.getMessage(), e);
            return Result.msgError("系统异常，发送失败: " + e.getMessage());
        }
    }
}
